/***
 * 
 *  Bluetooth.start("B88981******", "YES", function (res) {
 *
 *  console.log("返回OK", res);
 *
 *  })
 * 开门方法:
 *    第二个参数传入YES的时候.. 进行加密开门
 *    第二个参数传入NO的时候.. 为不加密开门
 * 
 * 返回值为:{OK: "OK", mac: "B88981******"}
 * 
 * 
 * 
 * 直接连接的方法
 * Bluetooth.ConnectTo("B88981E*****", "YES","7DF24921-****-****-****-**********",function(res){
 * 
 *     console.log("返回OK", res);
 * 
 * })
 * 
 */


const CryptoJS = require('crypto-js.js');

var Bluetooth = {};
var rssi;
var deviceId;
var serviceId;
var connectedDeviceId;
var notify_id;
var characteristicId;
var read_id;
var openDeviceName;
var keyMd5;
var inbleX;
// callBack
Bluetooth.start = function (deviceName, encryption, callBack) {
  var self = this;
  inbleX = encryption;
  wx.closeBluetoothAdapter({
    complete: function (res) {
      console.log(res)
      wx.openBluetoothAdapter({
        success: function (res) {
          console.log(res)
          wx.getBluetoothAdapterState({
            success: function (res) {
              console.log(res)
            }
          })
          wx.onBluetoothAdapterStateChange(function (res) { })
          wx.startBluetoothDevicesDiscovery({
            allowDuplicatesKey: false,
            success: function (res) {
              // 延时2秒判断时候找到设备
              deviceId = null;
              self.timedMsg(callBack);
              wx.onBluetoothDeviceFound(function (res) {
                // console.log("获取新设备成功了");
                // console.log(res);
                //剔除重复设备，兼容不同设备API的不同返回值
                var isnotexist = true
                var RSSI = -1000;
                if (res.devices[0].localName) {
                  var ServiceArray = res.devices[0]['advertisServiceUUIDs'];
                  if (ServiceArray != null) {
                    console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!");
                    var aa = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
                    for (var i = 0; i < res.devices[0]['advertisServiceUUIDs'].length; i++) {
                      if (res.devices[0]['advertisServiceUUIDs'][i] == aa) {
                        var name = res.devices[0]['name'];
                        var arr = deviceName.split(","); //传递进来的数组
                        var device = res.devices[0].localName;
                        var x = 0;
                        for (x in arr) {
                          // 判断数组中是否有这个设备
                          if (arr[x] == device) {
                            if (res.devices[0].RSSI > RSSI) {
                              rssi = res.devices[0].RSSI;
                              deviceId = res.devices[0].deviceId;
                              console.log("idididi", deviceId);
                              openDeviceName = res.devices[0].localName;
                              self.ConnectTo(null, null, null, callBack);
                            }
                          }
                        }
                      } else {
                        console.log("没找到");
                      }
                    }
                  }
                }
              })
            },
            fail: function (res) {
              console.log("扫描失败了");
            }
          })
        },
        fail: function (res) {
          wx.showModal({
            title: '提示',
            content: '请检查手机蓝牙是否打开',
            showCancel: false,
            success: function (res) { }
          })
        }
      })
    }
  })
}

Bluetooth.ConnectTo = function (deviceName, encryption, deviceID, callBack) {
  // Bluetooth.ConnectTo = function (callBack) {
  var self = this
  if (deviceID) {
    inbleX = encryption;//是否加密
    openDeviceName = deviceName;//名字
    deviceId = deviceID;
    // wx.closeBluetoothAdapter({});
    // wx.openBluetoothAdapter({});
    // wx.stopBluetoothDevicesDiscovery({});
    // wx.onBluetoothAdapterStateChange(function (res) { });

    wx.closeBluetoothAdapter({
      complete: function (res) {
        console.log(res)
        wx.openBluetoothAdapter({
          success: function (res) {
            console.log(res)
            wx.getBluetoothAdapterState({
              success: function (res) {

                wx.createBLEConnection({
                  deviceId: deviceId,
                  success: function (res) {
                    console.log("连接成功");
                    self.getService(callBack);
                  },
                  fail: function (res) {
                    console.log(res)
                    wx.hideLoading()
                    wx.showModal({
                      title: '提示',
                      content: '连接失败',
                      showCancel: false
                    })
                  }
                })
              }
            })
          }
        })
      }
    })
  } else {
    wx.stopBluetoothDevicesDiscovery({});
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        self.getService(callBack);
      },
      fail: function (res) {
        console.log(res)
        wx.hideLoading()
        wx.showModal({
          title: '提示',
          content: '连接失败',
          showCancel: false
        })
      }
    })
  }


}
// 延时操作
Bluetooth.timedMsg = function (callBack) {
  var self = this
  setTimeout(function () {
    if (deviceId == null) {
      self.stopDevices(callBack);
    }
  }, 1000);
}

Bluetooth.stopDevices = function (callBack) {
  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      callBack({
        state: "002",
        mac: "nil"
      });
    },
    fail: function (res) {

    }
  })
}

Bluetooth.getService = function (callBack) {
  var self = this

  // 监听蓝牙连接
  wx.onBLEConnectionStateChange(function (res) {
    console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`);
  });
  // 获取蓝牙设备service值
  wx.getBLEDeviceServices({
    deviceId: deviceId,
    success: function (res) {

      console.log("获取服务特性", res);

      serviceId = res.services[0].uuid;
      // 获取服务的特性
      self.getCharacter(callBack);
    }
  })
}

// 获取服务的特性
Bluetooth.getCharacter = function (callBack) {
  var self = this
  wx.getBLEDeviceCharacteristics({
    deviceId: deviceId,
    serviceId: serviceId,
    success: function (res) {
      for (let i = 0; i < res.characteristics.length; i++) {
        let charc = res.characteristics[i];
        if (charc.properties.notify) {
          notify_id = charc.uuid;
        }
        if (charc.properties.write) {
          characteristicId = charc.uuid;
        }
        if (charc.properties.write) {
          read_id = charc.uuid;
        }
      }
      wx.notifyBLECharacteristicValueChange({
        state: true,
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: notify_id,
        success: function (res) {
          setTimeout(function () {
            // 发送命令
            self.pushNot(callBack);
          }, 250);
          // 读取回调消息
          self.onNotifyChange(callBack);
        }
      })

    },
    fail: function (res) {
      // fail
      console.log("获取服务的特性GG");
    },
    complete: function (res) {
      // complete
    }
  }, 2000)
},
  // 发送命令
  Bluetooth.pushNot = function (callBack) {
    var self = this;
    if (inbleX == "YES") {
      var randomStr = random(); //随机数
      keyMd5 = CryptoJS.MD5(openDeviceName).toString()
      var encrypted = getAesString("i" + randomStr, keyMd5.toUpperCase()); //密文
      let buf = Str2Bytes(encrypted);
      keyMd5 = CryptoJS.MD5(randomStr).toString()
      writeBleTooth(buf);
    } else {
      let buf = self.str2ab("open@" + openDeviceName);
      console.log("发送不加密的命令");
      writeBleTooth(buf);
    }
  }

function writeBleTooth(buf) {

  wx.writeBLECharacteristicValue({
    deviceId: deviceId,
    serviceId: serviceId,
    characteristicId: characteristicId,
    value: buf,
    success: function (res) {
      console.log("success  指令发送成功");
    },
    fail: function (res) {
      console.log("指令发送GG");
    },
    complete: function (res) { }
  })
}

// 读取蓝牙返回值
//监听消息
Bluetooth.onNotifyChange = function (callBack) {
  var self = this;
  wx.onBLECharacteristicValueChange(function (res) {

    console.log("收到返回值", String.fromCharCode.apply(null, new Uint8Array(res.value)));
    if (inbleX == "YES") {
      var a = Bytes2HexString(res.value)
      var b = getDAesString(a, keyMd5.toUpperCase());
      try {
        if (b == "OK") {
          callBack({
            "state": "OK",
            "mac": openDeviceName
          })
          closeBluetooth();
        } else {
          if (b == openDeviceName) {
            var encrypted = getAesString("@" + openDeviceName, keyMd5.toUpperCase()); //密文
            let buf = Str2Bytes(encrypted);
            writeBleTooth(buf);
          }
        }
      } catch (e) {
        if (b != 'OK') {
          closeBluetooth();
          callBack({
            state: "NO",
            mac: openDeviceName
          })
        }
      }
    } else {
      let msg = String.fromCharCode.apply(null, new Uint8Array(res.value));
      try {
        if (msg == "OK") {
          callBack({
            state: "OK",
            mac: openDeviceName
          })
          closeBluetooth();
        }
      } catch (e) {
        closeBluetooth();
        if (msg != 'OK') {
          callBack({
            state: "NO",
            mac: openDeviceName
          })
        }
      }
    }
  })
}

function closeBluetooth() {
  wx.closeBluetoothAdapter({
    success: function (res) {
      console.log("断开蓝牙成功")
    }
  })
}

// 转换
Bluetooth.str2ab = function (str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint8Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

Bluetooth.str2abInbleX = function (str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint16Array(buf);
  for (var i = 0; i < str.length; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

Bluetooth.ab2str = function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

//十六进制字符串转字节数组
function Str2Bytes(str) {
  var pos = 0;
  var len = str.length;
  if (len % 2 != 0) {
    return null;
  }
  len /= 2;
  var hexA = new Array();
  for (var i = 0; i < len; i++) {
    var s = str.substr(pos, 2);
    var v = parseInt(s, 16);
    hexA.push(v);
    pos += 2;
  }
  let arrayBuffer = new Uint8Array(hexA).buffer;
  return arrayBuffer;
}

//字节数组转十六进制字符串，对负值填坑
function Bytes2HexString(buffer) {
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}


function random() {
  let array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
  var randomStr = "";
  for (var i = 0; i < 8; i++) {
    var a = Math.floor(Math.random() * 15);
    randomStr += array[a];
  }
  return randomStr;
}

function getAesString(data, key) { //加密

  var datas = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data), CryptoJS.enc.Utf8.parse(key), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7

  }).ciphertext.toString()
  return datas;
}

function getDAesString(encrypted, key) { //解密
  var encryptedHexStr = CryptoJS.enc.Hex.parse(encrypted);
  var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  var decrypted = CryptoJS.AES.decrypt(srcs, CryptoJS.enc.Utf8.parse(key), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  });
  return decrypted.toString(CryptoJS.enc.Utf8);
}

module.exports = Bluetooth;